package org.xtense.engine.actions;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.xtense.data.DBManager;
import org.xtense.engine.IConstants;
import org.xtense.log.iLog;
import org.xtense.model.CAttribute;
import org.xtense.model.CDocument;
import org.xtense.model.CElement;
import org.xtense.model.CText;
import org.xtense.model.PathEntry;
import org.xtense.util.StringUtil;

public class StoreAction extends XAction {	
	
	public StoreAction(String documentName) {
		super(new DBManager(), documentName);
	}

	public StoreAction(DBManager manager, String documentName) {
		super(manager, documentName);
	}

	public StoreAction(DBManager manager, int documentID) {
		super(manager, documentID);
	}

	public Object execute(Object o) {
		CDocument doc = (CDocument) o;

		ResultSet result = database
				.executeSqlQuery("SELECT MAX(documentId) FROM document");
		try {
			if (result.next())
				doc.setDocumentID(result.getInt(1) + 1);
			else
				doc.setDocumentID(1);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		iLog.info("Store the document info...");
		saveDoc(database, doc);
		iLog.info("Store the elements info...");
		saveElements(database, doc);
		iLog.info("Store the attributes info...");
		saveAttributes(database, doc);
		iLog.info("Store the text info...");
		saveTexts(database, doc);
		iLog.info("Store the path info...");
		savePath(database, doc);
		
		return null;
	}

	private void savePath(DBManager manager, CDocument doc) {
		Iterator<PathEntry> itp = doc.getPath().iterator();
		String values;
		String sql;
		PathEntry path;
		while (itp.hasNext()) {
			path = itp.next();
			values = StringUtil.append(new Object[] { path.getElmentPre(), ",",
					doc.getDocumentID(), ",'", path.getPathValue(), "'" });
			sql = MessageFormat.format(IConstants.Sql_Insert, new Object[] {
					IConstants.Path_Table, values });
			manager.executeSqlUpdate(sql);
		}

	}

	private void saveDoc(DBManager manager, CDocument doc) {
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

		String values = StringUtil.append(new Object[] { doc.getDocumentID(),
				",'", doc.getDocumentName(), "','", doc.getDocumentName(),
				"','", tempDate.format(new Date()), "'" });
		String sql = MessageFormat.format(IConstants.Sql_Insert, new Object[] {
				IConstants.Document_Table, values });
		manager.executeSqlUpdate(sql);
	}

	private void saveElements(DBManager manager, CDocument doc) {
		HashMap<Integer, CElement> cElements = doc.getElements();
		Iterator<CElement> itr = cElements.values().iterator();
		String values;
		String sql;
		CElement ele;
		while (itr.hasNext()) {
			ele = itr.next();
			values = StringUtil.append(new Object[] { ele.getElementPre(),
					",'", ele.getElementTag(), "',", doc.getDocumentID(), ",",
					ele.getParentPre() });
			sql = MessageFormat.format(IConstants.Sql_Insert, new Object[] {
					IConstants.Element_Table, values });
			manager.executeSqlUpdate(sql);
		}
	}

	private void saveAttributes(DBManager manager, CDocument doc) {
		HashMap<Integer, List<CAttribute>> cAttributes = doc.getAttributes();
		Iterator<List<CAttribute>> itrs = cAttributes.values().iterator();
		String values;
		String sql;
		Iterator<CAttribute> ia;
		CAttribute att;
		while (itrs.hasNext()) {
			ia = itrs.next().iterator();
			while (ia.hasNext()) {
				att = ia.next();
				values = StringUtil.append(new Object[] { "'",
						att.getAttributeName(), "','", att.getAttributeValue(),
						"',", doc.getDocumentID(), ",", att.getElementPre() });
				sql = MessageFormat.format(IConstants.Sql_Insert, new Object[] {
						IConstants.Attribute_Table, values });
				manager.executeSqlUpdate(sql);
			}
		}
	}

	private void saveTexts(DBManager manager, CDocument doc) {
		HashMap<Integer, CText> cTexts = doc.getText();
		Iterator<CText> itr = cTexts.values().iterator();
		CText text;
		String values;
		String sql;
		while (itr.hasNext()) {
			text = itr.next();
			values = StringUtil.append(new Object[] { "'",
					text.getTextContent(), "',", doc.getDocumentID(), ",",
					text.getElementPre() });
			sql = MessageFormat.format(IConstants.Sql_Insert, new Object[] {
					IConstants.Text_Table, values });
			manager.executeSqlUpdate(sql);

		}

	}
}
